package com.nbcio.cd.controller;

import cn.dev33.satoken.annotation.SaCheckPermission;
import com.nbcio.cd.domain.CdFolder;
import com.nbcio.cd.domain.vo.CdFolderVo;
import com.nbcio.cd.service.ICdFolderService;
import com.nbcio.common.core.domain.R;
import com.nbcio.common.web.core.BaseController;
import com.nbcio.common.log.annotation.Log;
import com.nbcio.common.log.enums.BusinessType;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import jakarta.validation.constraints.NotEmpty;
import jakarta.validation.constraints.NotNull;
import java.util.List;

/**
 * 云网盘文件夹Controller
 *
 * @author nbacheng
 */
@Slf4j
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/cd/folder")
public class CdFolderController {

    private final ICdFolderService cdFolderService;

    /**
     * 创建文件夹
     */
    @SaCheckPermission("cd:folder:add")
    @Log(title = "云网盘文件夹", businessType = BusinessType.INSERT)
    @PostMapping("/create")
    public R<CdFolderVo> createFolder(@RequestParam @NotEmpty(message = "文件夹名称不能为空") String folderName,
                                     @RequestParam @NotEmpty(message = "父文件夹ID不能为空") String parentIdStr,
                                     @RequestParam(required = false) Long projectId) {
        try {
            Long parentId = Long.parseLong(parentIdStr);
            CdFolderVo folderVo = cdFolderService.createFolder(folderName, parentId, projectId);
            return R.ok(folderVo);
        } catch (NumberFormatException e) {
            log.error("父文件夹ID格式错误: {}", parentIdStr);
            return R.fail("父文件夹ID格式错误");
        } catch (Exception e) {
            log.error("创建文件夹失败: {}", e.getMessage(), e);
            return R.fail("创建文件夹失败: " + e.getMessage());
        }
    }

    /**
     * 重命名文件夹
     */
    @SaCheckPermission("cd:folder:edit")
    @Log(title = "云网盘文件夹", businessType = BusinessType.UPDATE)
    @PutMapping("/rename")
    public R<Boolean> renameFolder(@RequestParam @NotNull(message = "文件夹ID不能为空") Long folderId,
                                  @RequestParam @NotEmpty(message = "新文件夹名称不能为空") String newName) {
        try {
            Boolean result = cdFolderService.renameFolder(folderId, newName);
            return R.ok(result);
        } catch (Exception e) {
            log.error("重命名文件夹失败: {}", e.getMessage(), e);
            return R.fail("重命名文件夹失败: " + e.getMessage());
        }
    }

    /**
     * 移动文件夹
     */
    @SaCheckPermission("cd:folder:edit")
    @Log(title = "云网盘文件夹", businessType = BusinessType.UPDATE)
    @PostMapping("/move")
    public R<Boolean> moveFolder(@RequestParam @NotNull(message = "文件夹ID不能为空") Long folderId,
                                @RequestParam @NotNull(message = "目标父文件夹ID不能为空") Long targetParentId) {
        try {
            Boolean result = cdFolderService.moveFolder(folderId, targetParentId);
            return R.ok(result);
        } catch (Exception e) {
            log.error("移动文件夹失败: {}", e.getMessage(), e);
            return R.fail("移动文件夹失败: " + e.getMessage());
        }
    }

    /**
     * 复制文件夹
     */
    @SaCheckPermission("cd:folder:edit")
    @Log(title = "云网盘文件夹", businessType = BusinessType.INSERT)
    @PostMapping("/copy")
    public R<Boolean> copyFolder(@RequestParam @NotNull(message = "文件夹ID不能为空") Long folderId,
                                @RequestParam @NotNull(message = "目标父文件夹ID不能为空") Long targetParentId) {
        try {
            Boolean result = cdFolderService.copyFolder(folderId, targetParentId);
            return R.ok(result);
        } catch (Exception e) {
            log.error("复制文件夹失败: {}", e.getMessage(), e);
            return R.fail("复制文件夹失败: " + e.getMessage());
        }
    }

    /**
     * 删除文件夹
     */
    @SaCheckPermission("cd:folder:remove")
    @Log(title = "云网盘文件夹", businessType = BusinessType.DELETE)
    @DeleteMapping("/{folderIds}")
    public R<Boolean> deleteFolders(@PathVariable @NotEmpty(message = "文件夹ID不能为空") Long[] folderIds) {
        try {
            Boolean result = cdFolderService.deleteFolders(List.of(folderIds));
            return R.ok(result);
        } catch (Exception e) {
            log.error("删除文件夹失败: {}", e.getMessage(), e);
            return R.fail("删除文件夹失败: " + e.getMessage());
        }
    }

    /**
     * 获取文件夹树
     */
    @SaCheckPermission("cd:folder:list")
    @GetMapping("/tree")
    public R<List<CdFolderVo>> getFolderTree(@RequestParam(required = false) Long userId,
                                            @RequestParam(required = false) Long projectId) {
        try {
            List<CdFolderVo> folderTree = cdFolderService.getFolderTree(userId, projectId);
            return R.ok(folderTree);
        } catch (Exception e) {
            log.error("获取文件夹树失败: {}", e.getMessage(), e);
            return R.fail("获取文件夹树失败: " + e.getMessage());
        }
    }

    /**
     * 查询文件夹列表
     */
    @SaCheckPermission("cd:folder:list")
    @GetMapping("/list")
    public R<List<CdFolderVo>> queryFolderList(@RequestParam @NotNull(message = "父文件夹ID不能为空") Long parentId,
                                                    @RequestParam(required = false) String folderName,
                                                    @RequestParam(required = false) String folderType,
                                                    CdFolderVo pageQuery) {
        try {
            return cdFolderService.queryFolderList(parentId, folderName, folderType, pageQuery);
        } catch (Exception e) {
            log.error("查询文件夹列表失败: {}", e.getMessage(), e);
            throw new RuntimeException("查询文件夹列表失败: " + e.getMessage());
        }
    }

    /**
     * 获取文件夹详情
     */
    @SaCheckPermission("cd:folder:query")
    @GetMapping("/{folderId}")
    public R<CdFolderVo> getFolderInfo(@PathVariable @NotNull(message = "文件夹ID不能为空") Long folderId) {
        try {
            CdFolderVo folderVo = cdFolderService.getFolderInfo(folderId);
            return R.ok(folderVo);
        } catch (Exception e) {
            log.error("获取文件夹详情失败: {}", e.getMessage(), e);
            return R.fail("获取文件夹详情失败: " + e.getMessage());
        }
    }

    /**
     * 检查文件夹权限
     */
    @SaCheckPermission("cd:folder:query")
    @GetMapping("/permission/{folderId}")
    public R<Boolean> checkFolderPermission(@PathVariable @NotNull(message = "文件夹ID不能为空") Long folderId,
                                           @RequestParam @NotEmpty(message = "权限类型不能为空") String permissionType) {
        try {
            Boolean hasPermission = cdFolderService.checkFolderPermission(folderId, permissionType);
            return R.ok(hasPermission);
        } catch (Exception e) {
            log.error("检查文件夹权限失败: {}", e.getMessage(), e);
            return R.fail("检查文件夹权限失败: " + e.getMessage());
        }
    }

    /**
     * 更新文件夹统计
     */
    @SaCheckPermission("cd:folder:edit")
    @PostMapping("/updateStats/{folderId}")
    public R<Void> updateFolderStats(@PathVariable @NotNull(message = "文件夹ID不能为空") Long folderId) {
        try {
            cdFolderService.updateFolderStats(folderId);
            return R.ok();
        } catch (Exception e) {
            log.error("更新文件夹统计失败: {}", e.getMessage(), e);
            return R.fail("更新文件夹统计失败: " + e.getMessage());
        }
    }

    /**
     * 获取用户根文件夹
     */
    @SaCheckPermission("cd:folder:query")
    @GetMapping("/userRoot")
    public R<CdFolderVo> getUserRootFolder(@RequestParam @NotNull(message = "用户ID不能为空") Long userId) {
        try {
            CdFolder rootFolder = cdFolderService.getUserRootFolder(userId);
            if (rootFolder == null) {
                return R.fail("用户根文件夹不存在");
            }
            
            // 转换为VO
            CdFolderVo folderVo = new CdFolderVo();
            folderVo.setFolderId(rootFolder.getFolderId());
            folderVo.setFolderName(rootFolder.getFolderName());
            folderVo.setParentId(rootFolder.getParentId());
            folderVo.setFolderPath(rootFolder.getFolderPath());
            folderVo.setFolderType(rootFolder.getFolderType());
            folderVo.setOwnerId(rootFolder.getOwnerId());
            folderVo.setProjectId(rootFolder.getProjectId());
            folderVo.setFolderSize(rootFolder.getFolderSize());
            folderVo.setFileCount(rootFolder.getFileCount());
            folderVo.setFolderCount(rootFolder.getFolderCount());
            folderVo.setIsShared(rootFolder.getIsShared());
            folderVo.setAccessLevel(rootFolder.getAccessLevel());
            folderVo.setStatus(rootFolder.getStatus());
            folderVo.setCreateBy(rootFolder.getCreateBy());
            folderVo.setCreateTime(rootFolder.getCreateTime());
            folderVo.setUpdateBy(rootFolder.getUpdateBy());
            folderVo.setUpdateTime(rootFolder.getUpdateTime());
            folderVo.setDelFlag(rootFolder.getDelFlag());
            folderVo.setCreateDept(rootFolder.getCreateDept());
            
            return R.ok(folderVo);
        } catch (Exception e) {
            log.error("获取用户根文件夹失败: {}", e.getMessage(), e);
            return R.fail("获取用户根文件夹失败: " + e.getMessage());
        }
    }

    /**
     * 获取项目根文件夹
     */
    @SaCheckPermission("cd:folder:query")
    @GetMapping("/projectRoot")
    public R<CdFolderVo> getProjectRootFolder(@RequestParam @NotNull(message = "项目ID不能为空") Long projectId) {
        try {
            CdFolder rootFolder = cdFolderService.getProjectRootFolder(projectId);
            CdFolderVo folderVo = new CdFolderVo();
            // 这里需要转换实体为VO，可以使用MapstructUtils
            return R.ok(folderVo);
        } catch (Exception e) {
            log.error("获取项目根文件夹失败: {}", e.getMessage(), e);
            return R.fail("获取项目根文件夹失败: " + e.getMessage());
        }
    }
}
